package com.cskaoyan.service.admin.goods;

import com.cskaoyan.dao.goods.*;
import com.cskaoyan.model.admin.goodsbean.*;
import com.cskaoyan.model.admin.goodsbean.bo.GoodsCreateBo;
import com.cskaoyan.model.admin.goodsbean.bo.GoodsProductBO;
import com.cskaoyan.model.admin.goodsbean.bo.GoodsUpdateBo;
import com.cskaoyan.model.admin.goodsbean.bo.list.GoodsListBO;
import com.cskaoyan.model.admin.goodsbean.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.crypto.hash.Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author AhaNg
 * @Date 2022/1/7 19:51
 * @description:
 * @return:
 */
@Service
@Transactional
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    BrandMapper brandMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    GoodsAttributeMapper goodsAttributeMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    GoodsKeywordsDao goodsKeywordsDao;


    //查询全部商品
    @Override
    public GoodsDataVO allGoodsList(GoodsListBO pageBO) {
        //分页
        PageHelper.startPage(pageBO.getPage(), pageBO.getLimit());
        //条件筛选
        GoodsExample goodsExample = new GoodsExample();
        GoodsExample.Criteria goodsExampleCriteria = goodsExample.createCriteria();
        goodsExampleCriteria.andDeletedEqualTo(false);
        //商品id和商品编号的精确查询
        if (pageBO.getGoodsId() != null) goodsExampleCriteria.andIdEqualTo(pageBO.getGoodsId());
        if (pageBO.getGoodsSn() != null && !pageBO.getGoodsSn().equals(""))
            goodsExampleCriteria.andGoodsSnEqualTo(pageBO.getGoodsSn());
        //商品名称的模糊查询
        if (pageBO.getName() != null && !pageBO.getName().equals(""))
            goodsExampleCriteria.andNameLike("%" + pageBO.getName() + "%");
        goodsExample.setOrderByClause(pageBO.getSort() + " " + pageBO.getOrder());

        List<Goods> goods = goodsMapper.selectByExample(goodsExample);
        PageInfo pageInfo = new PageInfo(goods);
        Integer pages = pageInfo.getPages();
        Integer total = (int) pageInfo.getTotal();
//
        GoodsDataVO goodsDataVO = new GoodsDataVO();
        goodsDataVO.setList(goods);
        goodsDataVO.setLimit(pageBO.getLimit());
        goodsDataVO.setPage(pageBO.getPage());
        goodsDataVO.setPages(pages);
        goodsDataVO.setTotal(total);

        return goodsDataVO;

    }

    //添加商品时的回显
    @Override
    public CatAndBrandVo CatAndBrand() {
        ArrayList<BrandListVo> brandListVos = new ArrayList<>();
        BrandExample brandExample = new BrandExample();
        List<Brand> brands = brandMapper.selectByExample(brandExample);
        for (Brand brand : brands) {
            brandListVos.add(new BrandListVo(brand.getId(), brand.getName()));
        }
        ArrayList<CategoryListVo> categoryListVos = new ArrayList<>();
        CategoryExample categoryExample = new CategoryExample();
        List<Category> categories = categoryMapper.selectByExample(categoryExample);
        //爸爸
        for (Category category : categories) {
            Integer pid = category.getPid();
            Category pCat = categoryMapper.selectByPrimaryKey(pid);
            if (pCat == null) continue;
            CategoryListVo categoryListVo = new CategoryListVo(pCat.getId(), pCat.getName());
            //子标签
            ArrayList<CategoryListOfChildrenVo> categoryListOfChildrenVos = new ArrayList<>();
            CategoryExample categoryExample2 = new CategoryExample();
            categoryExample2.createCriteria().andPidEqualTo(pid);
            List<Category> sonCategories = categoryMapper.selectByExample(categoryExample2);
            for (Category sonCategory : sonCategories) {
                categoryListOfChildrenVos.add(new CategoryListOfChildrenVo(sonCategory.getId(), sonCategory.getName()));
            }
            categoryListVo.setChildren(categoryListOfChildrenVos);
            //去除重复的爸爸
            if (categoryListVos.contains(categoryListVo)) continue;
            categoryListVos.add(categoryListVo);
        }
        return new CatAndBrandVo(brandListVos, categoryListVos);
    }

    //创建商品
    @Override
    public void create(GoodsCreateBo goodsCreateBo) {
        Goods goods = new Goods();
//        Goods goods = goodsCreateBo.getGoods();
        List<GoodsAttribute> goodsAttribute = goodsCreateBo.getAttributes();
        List<GoodsProductBO> goodsProduct = goodsCreateBo.getProducts();
        List<GoodsSpecification> goodsSpecification = goodsCreateBo.getSpecifications();
        Date date = new Date();
        goods.setAddTime(date);
        goods.setDeleted(false);
        convertTypeA2TypeB(goodsCreateBo.getGoods(), goods);
        goodsMapper.insertSelective(goods);

        for (GoodsAttribute attribute : goodsAttribute) {
            attribute.setAddTime(date);
            attribute.setDeleted(false);
            attribute.setGoodsId(goods.getId());
            goodsAttributeMapper.insertSelective(attribute);
        }
        for (GoodsSpecification specification : goodsSpecification) {
            specification.setAddTime(date);
            specification.setDeleted(false);
            specification.setGoodsId(goods.getId());
            goodsSpecificationMapper.insertSelective(specification);
        }
        for (GoodsProductBO productBO : goodsProduct) {
            productBO.setAddTime(date);
            productBO.setDeleted(false);
            productBO.setGoodsId(goods.getId());
            GoodsProduct product = new GoodsProduct();
            convertTypeA2TypeB(productBO, product);
            goodsProductMapper.insertSelective(product);
        }
    }

    //查询商品详情
    @Override
    public GoodsDetailVo detail(Integer id) {

        Goods goods = goodsMapper.selectByPrimaryKey(id);

        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(id);
        List<GoodsAttribute> goodsAttributes = goodsAttributeMapper.selectByExample(goodsAttributeExample);

        GoodsProductExample goodsProductExample = new GoodsProductExample();
        goodsProductExample.createCriteria().andGoodsIdEqualTo(id);
        List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(goodsProductExample);

        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
        goodsSpecificationExample.createCriteria().andGoodsIdEqualTo(id);
        List<GoodsSpecification> goodsSpecifications = goodsSpecificationMapper.selectByExample(goodsSpecificationExample);

        Integer categoryId = goods.getCategoryId();
        Category category = categoryMapper.selectByPrimaryKey(categoryId);
        Integer pid = category.getPid();
        Integer[] integers = {pid, categoryId};

        GoodsDetailVo goodsDetailVo = new GoodsDetailVo();
        goodsDetailVo.setGoods(goods);
        goodsDetailVo.setAttributes(goodsAttributes);
        goodsDetailVo.setProducts(goodsProducts);
        goodsDetailVo.setSpecifications(goodsSpecifications);
        goodsDetailVo.setCategoryIds(integers);

        return goodsDetailVo;
    }

    /***
     *  新增了更新keyword表的逻辑
     */
    @Override
    public void update(GoodsUpdateBo goodsUpdateBo) {
        Date date = new Date();
        Goods goods = goodsUpdateBo.getGoods();
        List<GoodsProduct> products = goodsUpdateBo.getProducts();
        List<GoodsAttribute> attributes = goodsUpdateBo.getAttributes();
        List<GoodsSpecification> specifications = goodsUpdateBo.getSpecifications();


        goods.setUpdateTime(date);


        updateKeywordInfo(goods.getKeywords(), goods.getId());
//        if (products == null || products.isEmpty()) {
//            goods.setRetailPrice("0");
//        } else {
//            goods.setRetailPrice(products.get(0).getPrice().toString());
//        }
        goodsMapper.updateByPrimaryKeyWithBLOBs(goods);
        Integer goodsId = goods.getId();

        for (GoodsAttribute attribute : attributes) {
            if (attribute.getId() == null) {
                attribute.setGoodsId(goodsId);
                attribute.setAddTime(date);
                attribute.setDeleted(false);
                goodsAttributeMapper.insertSelective(attribute);
            }
            if (attribute.getDeleted()) {
                goodsAttributeMapper.deleteByPrimaryKey(attribute.getId());
            }
            attribute.setUpdateTime(date);
            goodsAttributeMapper.updateByPrimaryKeySelective(attribute);
        }
        for (GoodsProduct product : products) {
            product.setUpdateTime(date);
            goodsProductMapper.updateByPrimaryKeySelective(product);
        }
        for (GoodsSpecification specification : specifications) {
            specification.setUpdateTime(date);
            goodsSpecificationMapper.updateByPrimaryKeySelective(specification);
        }
    }

    /**
     * @param keyword:关键词
     */
    private void updateKeywordInfo(String keyword, Integer goodsId) {
        if (keyword == null || keyword.isEmpty()) {
            return;
        }
        List<KeywordDto> goodsAllKeyword = goodsKeywordsDao.getGoodsAllKeyword(goodsId);
        String[] split = keyword.split(",");
        Set<String> set = goodsAllKeyword.stream().map(KeywordDto::getKeyword).collect(Collectors.toSet());
        for (String s : split) {
            set.add(s.trim());
        }

        List<KeywordDto> delete = new ArrayList<>();
        // set中的元素经过增加只会比原来更多，如果set中不包含就代表已经被删除
        for (KeywordDto keywordDto : goodsAllKeyword) {
            if (!set.contains(keywordDto.getKeyword())) {
                keywordDto.setDeleted(1);
                delete.add(keywordDto);
            } else {
                // 如果包含就删除，set中剩下的就是新增的
                set.remove(keywordDto.getKeyword());
            }
        }
        // 数量不为0代表有元素需要被删除
        if (delete.size() != 0) {
            goodsKeywordsDao.deleteKeyWord(delete);
        }
        // 新增一些关键词，如果set的size不为零才代表有数据
        if (set.size() != 0) {
            goodsKeywordsDao.addNewKeyWord(set, goodsId);
        }

    }

    @Override
    public void delete(Goods goods) {
        Integer goodsId = goods.getId();
        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        GoodsProductExample goodsProductExample = new GoodsProductExample();
        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();

        goodsAttributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsProductExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsSpecificationExample.createCriteria().andGoodsIdEqualTo(goodsId);

        goodsMapper.deleteByPrimaryKey(goodsId);
        goodsAttributeMapper.deleteByExample(goodsAttributeExample);
        goodsProductMapper.deleteByExample(goodsProductExample);
        goodsSpecificationMapper.deleteByExample(goodsSpecificationExample);
    }

    /**
     * @Author: AhaNg
     * @description: 创建商品时的接收参数转换的方法
     * @return:
     */

    private <T, E> void convertTypeA2TypeB(T fromType, E toType) {
        for (Field declaredField : fromType.getClass().getDeclaredFields()) {
            for (Field field : toType.getClass().getDeclaredFields()) {
                if (declaredField.getName().equals(field.getName())) {
                    declaredField.setAccessible(true);
                    field.setAccessible(true);
                    if (declaredField.getName().equals("gallery") || declaredField.getName().equals("specifications")) {
                        try {
                            String str = (String) field.get(toType);
                            str = "[";
                            for (String s : (List<String>) declaredField.get(fromType)) {
                                str += s + ",";
                            }
                            str += "]";
                            str = str.replaceAll("(,\\])$", "]");
                            String[] arr;
                            if (str.length() == 2) {
                                arr = new String[0];
                            } else {
                                arr = str.substring(0, str.length() - 1).split(",");
                            }
                            field.set(toType, arr);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    } else {
                        try {
                            field.set(toType, declaredField.get(fromType));
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}
